package com.loveprogrammer.eternity.task;

import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.loveprogrammer.eternity.action.BaseAction;
import com.loveprogrammer.eternity.factory.EquipmentFactory;
import com.loveprogrammer.eternity.factory.MissionFactory;
import com.loveprogrammer.eternity.factory.template.MissionTemplate;
import com.loveprogrammer.eternity.model.game.HeroWrapper;
import com.loveprogrammer.eternity.model.game.TaskManager;
import com.loveprogrammer.eternity.model.mission.MissionDefinition;
import com.loveprogrammer.eternity.model.mission.MissionReward;
import com.loveprogrammer.eternity.model.mission.support.KillMonsterMission;
import com.loveprogrammer.eternity.model.task.TaskDefinition;
import com.loveprogrammer.eternity.utils.ScannerInput;
import lombok.Data;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Data
public class MainTaskService extends BaseAction {

    private List<MissionTemplate> missionTemplates;

    private List<TaskDefinition> taskDefinitionList;

    private Map<String, TaskDefinition> taskMap;

    /***
     *  初始化所有任务
     */
    public void init() throws Exception {
        if (taskDefinitionList == null) {
            taskDefinitionList = new ArrayList<>();
        }

        // 读取配置文件，然后加载到weaponTemplates中
        ClassLoader classLoader = EquipmentFactory.class.getClassLoader();

        InputStream inputStream = classLoader.getResourceAsStream("mission/missions.json");

        BufferedReader streamReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        StringBuilder responseStrBuilder = new StringBuilder();

        String inputStr;
        while ((inputStr = streamReader.readLine()) != null)
            responseStrBuilder.append(inputStr);

        missionTemplates = JSONArray.parseArray(responseStrBuilder.toString(), MissionTemplate.class);
        TaskDefinition definition;
        for (MissionTemplate missionTemplate : missionTemplates) {
            //
            definition = new TaskDefinition();
            definition.setTaskId(missionTemplate.getTaskId());
            definition.setName(missionTemplate.getName());

            MissionDefinition mission = new MissionFactory().MissionBuilder()
                    .className(missionTemplate.getMissionClassName())
                    .params(missionTemplate.getPrams())
                    .taskTargetType(missionTemplate.getTaskTargetType())
                    .rewardClassName(missionTemplate.getRewardClassName())
                    .rewardParams(missionTemplate.getRewardParams())
                    .rewardProperties(missionTemplate.getProperties())
                    .rewardGoldCoin(missionTemplate.getRewardGoldCoin())
                    .rewardDiamonds(missionTemplate.getRewardDiamonds())
                    .rewardExp(missionTemplate.getRewardExp())
                    .builder();

            definition.setMission(mission);
            definition.setMissionClass(missionTemplate.getMissionClassName());
            definition.setMissionRewardClass(missionTemplate.getRewardClassName());
            definition.setClaimNpcId(missionTemplate.getClaimNpcId());
            definition.setClaimMapId(missionTemplate.getClaimMapId());
            definition.setClaimDialogue(missionTemplate.getClaimDialogue());
            definition.setCheckTaskDialogue(missionTemplate.getCheckTaskDialogue());
            definition.setStatus(0);
            definition.setSubmitNpcId(missionTemplate.getSubmitNpcId());
            definition.setSubmitMapId(missionTemplate.getSubmitMapId());
            definition.setSubmitDialogue(missionTemplate.getSubmitDialogue());

            definition.setPreTaskIds(missionTemplate.getPreTaskIds());
            definition.setNextTaskIds(missionTemplate.getNextTaskIds());
            definition.setMissionDesc(missionTemplate.getMissionDesc());

            taskDefinitionList.add(definition);
        }


        taskMap = taskDefinitionList.stream().collect(Collectors.toMap(TaskDefinition::getTaskId, e -> e));

    }

    public void checkTask(String npcId, String mapId, HeroWrapper hero) {
        List<TaskDefinition> success = new ArrayList<>();
        List<TaskDefinition> wait = new ArrayList<>();
        // 查看当前英雄的任务完成情况
        TaskManager taskManager = hero.getTaskManager();
        List<TaskDefinition> completeTasks = taskManager.getCompleteTasks();
        // 检查任务完成情况
        ConcurrentHashMap<String, TaskDefinition> taskBeans = taskManager.getTaskBeans();

        // 检查可接任务
        int choose;
        for (TaskDefinition taskDefinition : taskDefinitionList) {
            // 校验地图和npc
            if(StringUtils.isEmpty(mapId) || mapId.equals(taskDefinition.getClaimMapId()) || mapId.equals(taskDefinition.getSubmitMapId())) {
                if (StringUtils.isEmpty(npcId) || npcId.equals(taskDefinition.getClaimNpcId()) || npcId.equals(taskDefinition.getSubmitNpcId())) {
                    if (taskBeans.get(taskDefinition.getTaskId()) != null) {
                        wait.add(taskBeans.get(taskDefinition.getTaskId()));
                    } else if (completeTasks.contains(taskDefinition)) {
                        int index = completeTasks.indexOf(taskDefinition);
                        wait.add(completeTasks.get(index));
                    } else {
                        wait.add(taskDefinition);
                    }
                }
            }
        }
        if(CollectionUtils.isEmpty(wait)){
            eventManager.notifyMessage("", 1);
            return;
        }

        int index = 1;
        // 只显示已完成的和上一个任务完成或者没有上一个任务限制的任务
        checkWaitTask(wait,hero,taskManager);
        for (int i = 0; i < wait.size(); i++) {
            TaskDefinition taskDefinition = wait.get(i);
            if (taskDefinition.getStatus() == 0) {
                eventManager.notifyMessage(index++ + ":" + taskDefinition.getName() + ": " + " 未接受", 1);
            } else if (taskDefinition.getStatus() == 1) {
                eventManager.notifyMessage(index++ + ":" + taskDefinition.getName() + ": " + " 进行中", 1);
            } else if (taskDefinition.getStatus() == 3) {
                eventManager.notifyMessage(index++ + ":" + taskDefinition.getName() + ": " + " 任务完成-可领取奖励", 1);
            } else if (taskDefinition.getStatus() == 5) {
                eventManager.notifyMessage(index++ + ":" + taskDefinition.getName() + ": " + " 任务完成-已领取奖励", 1);
            }
        }
        eventManager.notifyMessage("请选择任务，0-退出", 1);
        choose = ScannerInput.inputInt(1, index, 0);
        while (choose != 0) {
            TaskDefinition taskDefinition = wait.get(choose - 1);
            MissionDefinition mission = taskDefinition.getMission();
            if (taskDefinition.getStatus() == 0) {
                eventManager.notifyMessage(taskDefinition.getClaimDialogue(), 1);
                // 要选择的
                eventManager.notifyMessage("请选择是否接受任务，1-接受 2-不接受 0 退出", 1);
                choose = ScannerInput.inputInt(1, 2, 0);
                if (choose == 1) {
                    taskDefinition.setStatus(1);
                    taskManager.addTask(taskDefinition);
                    eventManager.notifyMessage("接受新任务" + taskDefinition.getName() + ":" + taskDefinition.getMissionDesc(), 1);
                }
            } else if (taskDefinition.getStatus() == 1) {
                eventManager.notifyMessage(taskDefinition.getCheckTaskDialogue(), 1);
            } else if (taskDefinition.getStatus() == 3) {
                eventManager.notifyMessage(taskDefinition.getSubmitDialogue(), 1);
                MissionReward reward = mission.getReward();
                hero.rewordGoods(reward);
                taskDefinition.setStatus(5);
                taskManager.completeClaim(taskDefinition);
            } else if (taskDefinition.getStatus() == 5) {
                eventManager.notifyMessage("任务已经完成", 1);
            }


            index = 1;
            // 只显示已完成的和上一个任务完成或者没有上一个任务限制的任务
            checkWaitTask(wait,hero, taskManager);
            for (int i = 0; i < wait.size(); i++) {
                taskDefinition = wait.get(i);
                if (taskDefinition.getStatus() == 0) {
                    eventManager.notifyMessage(index++ + ":" + taskDefinition.getName() + ": " + " 未接受", 1);
                } else if (taskDefinition.getStatus() == 1) {
                    eventManager.notifyMessage(index++ + ":" + taskDefinition.getName() + ": " + " 进行中", 1);
                } else if (taskDefinition.getStatus() == 3) {
                    eventManager.notifyMessage(index++ + ":" + taskDefinition.getName() + ": " + " 任务完成-可领取奖励", 1);
                } else if (taskDefinition.getStatus() == 5) {
                    eventManager.notifyMessage(index++ + ":" + taskDefinition.getName() + ": " + " 任务完成-已领取奖励", 1);
                }
            }
            eventManager.notifyMessage("请选择任务，0-退出", 1);
            choose = ScannerInput.inputInt(1, index, 0);
        }
    }

    private void checkWaitTask(List<TaskDefinition> wait,HeroWrapper hero,TaskManager taskManager) {
        Set<String> completeIds = new HashSet<>();
        wait.forEach(taskDefinition -> {
            if(taskDefinition.getStatus() == 1){
                MissionDefinition mission = taskDefinition.getMission();
                if(mission.checkTaskComplete(hero)) {
                    taskManager.complete(taskDefinition, mainTaskService);
                }
            }
        });

        wait.stream().filter(e -> e.getStatus()>2).forEach(task -> {
            completeIds.add(task.getTaskId());
        });

        Iterator<TaskDefinition> iterator = wait.iterator();
        while (iterator.hasNext()) {
            TaskDefinition taskDefinition = iterator.next();
            if(CollectionUtils.isEmpty(taskDefinition.getPreTaskIds())){
                continue;
            }
            // 进行中
            if(taskDefinition.getStatus() > 1 ){
                continue;
            }
            // 剩下的只能是前置任务完成的
            List<String> preTaskIds = taskDefinition.getPreTaskIds();
            if(completeIds.containsAll(preTaskIds)){
                continue;
            }
            iterator.remove();
        }
    }

    public static void main(String[] args) throws Exception {
        MainTaskService service = new MainTaskService();
        service.init();
        System.out.println(JSON.toJSONString(service.getTaskDefinitionList()));
    }


    public void complete(String taskId) {
        TaskDefinition taskDefinition = taskMap.get(taskId);
        taskDefinition.setStatus(3);
    }

    public void updateMissionStatus(TaskManager taskManager) {
        // 更新任务进度
        List<TaskDefinition> tasks = taskManager.getAllTasks();

        ConcurrentHashMap<String, TaskDefinition> hisTasks = taskManager.getHisTasks();
        ConcurrentHashMap<String, TaskDefinition> taskBeans = taskManager.getTaskBeans();
        ConcurrentHashMap<String, TaskDefinition> killMonsterTasks = taskManager.getKillMonsterTasks();
        List<TaskDefinition> completeTasks = taskManager.getCompleteTasks();

        for (TaskDefinition task : tasks) {
            TaskDefinition taskDefinition = taskMap.get(task.getTaskId());
            if (taskDefinition != null) {
                // 状态
                Integer taskStatus = task.getStatus();
                taskDefinition.setStatus(taskStatus);
                // 任务同步 0 未开始 1 进行中 2 暂定 3 待领奖 5 已完成  9 放弃
                // MissionDefinition mission = taskDefinition.getMission();
                MissionDefinition mission = task.getMission();
                mission.setReward(taskDefinition.getMission().getReward());
                taskDefinition.setMission(mission);

                TaskDefinition definition = taskBeans.get(task.getTaskId());
                if (definition != null) {
                    definition.setMission(mission);
                }
                TaskDefinition hisDefinition = hisTasks.get(task.getTaskId());
                if (hisDefinition != null) {
                    hisDefinition.setMission(mission);
                }

                if(mission instanceof KillMonsterMission) {
                    KillMonsterMission missionK = (KillMonsterMission) mission;
                    TaskDefinition killDefinition = killMonsterTasks.get(String.valueOf(missionK.getMonsterId()));
                    if (killDefinition != null) {
                        killDefinition.setMission(mission);
                    }
                }

                // 已完成
                Optional<TaskDefinition> optional = completeTasks.stream().filter(e -> e.getTaskId().equals(task.getTaskId())).findFirst();
                if(optional.isPresent()) {
                    TaskDefinition definitionComplete = optional.get();
                    definitionComplete.setMission(mission);
                }
            }
        }

    }
}
